home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / misc / emu / p-interp.lha / p-interp-0.4 / Term.c < prev    next >
C/C++ Source or Header  |  2001-06-11  |  10KB  |  484 lines

  1. /*
  2.  
  3.   P-Code interpreter (to run the apple pascal system)
  4.   Copyright (C) 2000 Mario Klebsch
  5.  
  6.   This program is free software; you can redistribute it and/or modify
  7.   it under the terms of the GNU General Public License as published by
  8.   the Free Software Foundation; either version 2 of the License, or
  9.   (at your option) any later version.
  10.  
  11.   This program is distributed in the hope that it will be useful,
  12.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.   GNU General Public License for more details.
  15.  
  16.   You should have received a copy of the GNU General Public License
  17.   along with this program; if not, write to the Free Software
  18.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20.   $Log: Term.c,v $
  21.   Revision 1.5  2001/06/07 20:03:10  mario
  22.   Anfang der Integration von Amiga-Patches, die Stefan A. Haubenthal
  23.   <polluks@web.de> mir geschickt hat. Es ist aber erst der Ausgabe-Teil
  24.   fertig, die Anpassungen der Eingaberoutinen sind daher noch nicht
  25.   integriert.
  26.  
  27.   Revision 1.4  2001/05/26 15:13:29  mario
  28.   Diverse kleine Fehler behoben, fehlende #includes, Labels ohne Statement
  29.   dahinter, ...
  30.  
  31.   Revision 1.3  2001/05/20 20:14:40  mario
  32.   Neues Gerät PRINTER: implementiert
  33.  
  34.   Revision 1.2  2001/05/20 13:12:02  mario
  35.   CVS-Idents und Logs eingefügt
  36.  
  37.  
  38. */
  39.  
  40. #ident "$Id: Term.c,v 1.5 2001/06/07 20:03:10 mario Exp $";
  41.  
  42. #include <fcntl.h>
  43. #include <stdlib.h>
  44. #include <stdio.h>
  45. #include <unistd.h>
  46. #include <string.h>
  47. #ifndef _AMIGA
  48. #include <curses.h>
  49. #include <term.h>
  50. #include <termios.h>
  51. #include <assert.h>
  52. #include <sys/time.h>
  53. #include <sys/types.h>
  54. #include <sys/stat.h>
  55. #include <sys/socket.h>
  56. #include <netinet/in.h>
  57. #endif
  58.  
  59. #include "psystem.h"
  60. #include "Memory.h"
  61. #include "Term.h"
  62.  
  63. static int BatchMode=0;
  64. static int TermIn=-1;
  65. static int TermOut=-1;
  66. #ifndef _AMIGA
  67. struct termios    OldTerm;
  68. #else
  69. static char *clr_eol        = "\x9bK";
  70. static char *clr_eos        = "\x9bJ";
  71. static char *clear_screen   = "\x9b""2J";
  72. static char *insert_line    = "\x9bL";
  73. static char *cursor_home    = "\x9bH";
  74. static char *cursor_up      = "\x9b""A";
  75. static char *cursor_right   = "\x9b""C";
  76. static char *cursor_address = "\x9b%d;%dH";
  77. #define tgoto(cursor_address, x, y) s="",sprintf(s, cursor_address, y+1, x+1)
  78. #endif /* _AMIGA */
  79. /*
  80.  
  81.   erase line=0
  82.   erase to end of screen=11
  83.   erase screen=12
  84.   insert line=22
  85.   move cursor home=25
  86.   move cursor right=28
  87.   erase to end of line=29
  88.   gotoxy=30
  89.   move cursor up=31
  90.  
  91.  */
  92.  
  93. void TermWrite(char ch, word Mode)
  94. {
  95.   static int state=0;
  96.   static int x;
  97.   int         y;
  98.   char         *s;
  99.  
  100.   switch(state)
  101.     {
  102.     case 0:
  103.       switch(ch)
  104.     {
  105.     case 0:                /* erase line ???            */
  106.       if (!(Mode&0x8))
  107.         ;
  108.       else
  109.         write(TermOut, &ch, 1);
  110.       break;
  111.     case 7:
  112.       if (!BatchMode)
  113.         write(TermOut, &ch, 1);
  114.       break;
  115.     case 11:            /* erase to end of screen        */
  116.       if (!BatchMode && clr_eos)
  117.         write(TermOut, clr_eos, strlen(clr_eos));
  118.       break;
  119.     case 12:            /* erase screen                */
  120.       if (!BatchMode && clear_screen)
  121.         write(TermOut, clear_screen, strlen(clear_screen));
  122.       break;
  123.     case 13:            /* carriage return            */
  124.       if (!(Mode&0x4))
  125.         if (!BatchMode)
  126.           write(TermOut,"\r\n", 2);
  127.         else
  128.           write(TermOut,"\n", 1);
  129.       else
  130.         write(TermOut, &ch, 1);
  131.       break;
  132.     case 16:            /* DLE prefix                */
  133.       if (!(Mode&0x8))
  134.         state=3;
  135.       break;
  136.     case 22:
  137.       if (!BatchMode && insert_line)
  138.         write(TermOut, insert_line, strlen(insert_line));
  139.       break;
  140.     case 25:            /* move cursor home            */
  141.       if (!BatchMode && cursor_home)
  142.         write(TermOut, cursor_home, strlen(cursor_home));
  143.       else
  144.         write(TermOut,"\n", 1);
  145.       break;
  146.     case 28:            /* move cursor right            */
  147.       if (!BatchMode && cursor_right)
  148.         write(TermOut, cursor_right, strlen(cursor_right));
  149.       break;
  150.     case 29:            /* erase to end of line            */
  151.       if (!BatchMode && clr_eol)
  152.         write(TermOut, clr_eol, strlen(clr_eol));
  153.       break;
  154.     case 30:            /* gotoxy                */
  155.       state=1;
  156.       break;
  157.     case 31:            /* move cursor up            */
  158.       if (!BatchMode && cursor_up)
  159.         write(TermOut, cursor_up, strlen(cursor_up));
  160.       break;
  161.     default:
  162.       write(TermOut, &ch, 1);
  163.       break;
  164.     }
  165.       break;
  166.     case 1:
  167.       x=ch-' ';
  168.       state=2;
  169.       break;
  170.     case 2:                /* gotoxy complete            */
  171.       y=ch-' ';
  172.       if (!BatchMode && cursor_address)
  173.     {
  174.       s=tgoto(cursor_address, x, y);
  175.       write(TermOut, s, strlen(s));
  176.     }
  177.       state=0;
  178.       break;
  179.     case 3:                /* char after DLE            */
  180.       ch -= 0x20;
  181.       while (ch--)
  182.     write(TermOut, " ", 1);
  183.       state=0;
  184.       break;
  185.     }
  186. }
  187.  
  188. #ifndef _AMIGA
  189. static struct translator
  190. {
  191.   struct translator    *Next;
  192.   char            *Pattern;
  193.   byte            Key;
  194.   void            (*Action)(byte);
  195. } *Keys=NULL;
  196.  
  197. static void AddKeyTranslation(byte Key, char *Pattern, void (*Action)(byte))
  198. {
  199.   struct translator    *NewKey=malloc(sizeof(struct translator));
  200.   assert(NewKey);
  201.   NewKey->Key     = Key;
  202.   NewKey->Pattern = Pattern;
  203.   NewKey->Action  = Action;
  204.   NewKey->Next    = Keys;
  205.   Keys=NewKey;
  206. }
  207.  
  208. char TermRead(void)
  209. {
  210.   unsigned char    ch;
  211.  
  212.   static int    state=0;
  213.   static int    BufIdx=0;
  214.   static char    Buffer[10];
  215.  
  216.   if (state==0)
  217.     while (1)
  218.       {
  219.     fd_set        fds;
  220.     struct timeval    tv;
  221.     FD_ZERO(&fds);
  222.     FD_SET(TermIn, &fds);
  223.     tv.tv_sec = 0;
  224.     tv.tv_usec = 25000;
  225.     
  226.     if (select(TermIn+1, &fds, NULL, NULL, BufIdx?&tv:NULL)>0)
  227.       {                /* Ein Zeichen ist verfügbar        */
  228.         struct translator *t;
  229.         int    Match=0;
  230.  
  231.         if (read(TermIn, &ch, 1)<1)    /* Lesen und in Puffer speichern    */
  232.           if (BatchMode)
  233.         exit(0);
  234.  
  235. #ifndef XXX
  236.         if (ch=='\0')    /* XXX Quick-Hack :-( */
  237.           continue;
  238. #endif
  239.  
  240.         Buffer[BufIdx++]=ch;
  241.         for (t=Keys; t; t=t->Next)
  242.           {
  243.         int    i;
  244.         for (i=0; i< BufIdx; i++)
  245.           if (Buffer[i] != t->Pattern[i])
  246.             goto next;
  247.         if (!(t->Pattern[BufIdx]))    /* full Pattern match */
  248.           {
  249.             BufIdx=0;
  250.             return (t->Key);
  251.           }
  252.         Match=1;
  253.         break;
  254.           next:
  255.         ;
  256.           }
  257.         if (!Match)
  258.           goto ret;
  259.       }
  260.     else                /* Timeout                */
  261.       {
  262.       ret:
  263.         if (BufIdx>1)
  264.           state=1;
  265.         else
  266.           BufIdx=0;
  267.         return(Buffer[0]);
  268.       }
  269.       }
  270.   else
  271.     {
  272.       ch=Buffer[state++];
  273.       if (state >=BufIdx)
  274.     {
  275.       state=0;
  276.       BufIdx=0;
  277.     }
  278.       return(ch);
  279.     }
  280. }
  281.  
  282. int TermStat(void)
  283. {
  284.   fd_set        fds;
  285.   struct timeval    tv;
  286.   FD_ZERO(&fds);
  287.   FD_SET(TermIn, &fds);
  288.   tv.tv_sec = 0;
  289.   tv.tv_usec = 0;
  290.     
  291.   if (select(TermIn+1, &fds, NULL, NULL, &tv)>0)
  292.     return(1);
  293.   else
  294.     return(0);
  295. }
  296.  
  297. static void OpenXTerm(void)
  298. {
  299.   int            i;
  300.   int            s;
  301.   struct sockaddr_in    addr;
  302.   char            Buffer[256];
  303.       
  304.   unsigned char        TelnetInit[]=
  305.   { 255, 253, 3,
  306.     255, 251, 3,
  307.     255, 251, 1
  308.   };
  309.  
  310.   if ((s=socket(PF_INET, SOCK_STREAM, 0))<0)
  311.     {
  312.       perror("socket()");
  313.       exit(1);
  314.     }
  315.   addr.sin_family=AF_INET;
  316.   addr.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
  317.   addr.sin_port=htons(0);
  318.   if (bind(s, (struct sockaddr*)&addr, sizeof(addr))<0)
  319.     {
  320.       perror("bind()");
  321.       exit(1);
  322.     }
  323.   if (listen(s,1)<0)
  324.     {
  325.       perror("listen()");
  326.       exit(1);
  327.     }
  328.   i=sizeof(addr);
  329.   if (getsockname(s, (struct sockaddr*)&addr, &i)<0)
  330.     {
  331.       perror("getsockname()");
  332.       exit(1);
  333.     }
  334.   
  335.   snprintf(Buffer, sizeof(Buffer), "xterm -geometry 80x24 -e "
  336.        "telnet -E localhost %d&", ntohs(addr.sin_port));
  337.   system(Buffer);
  338.   
  339.   i=sizeof(addr);
  340.   if ((TermOut=accept(s, (struct sockaddr*)&addr, &i))<0)
  341.     {
  342.       perror("accept()");
  343.       exit(1);
  344.     }
  345.  
  346.   close(s);
  347.  
  348.   write(TermOut, TelnetInit, sizeof(TelnetInit));
  349.   for (i=0; i<sizeof(TelnetInit); i++)
  350.     read(TermOut, &s, 1);
  351. }
  352.  
  353. void TermOpen(int UseXTerm, int BatchFd)
  354. {
  355.   struct termios    NewTerm;
  356.  
  357.   if (BatchFd<0)
  358.     BatchMode=0;
  359.   else
  360.     {
  361.       BatchMode=1;
  362.       TermIn=BatchFd;
  363.     }
  364.  
  365.   if (UseXTerm)
  366.     {
  367.       OpenXTerm();
  368.       setupterm("xterm", TermOut, NULL);
  369.     }
  370.   else
  371.     {
  372.       if (BatchMode)
  373.     {
  374.       TermOut=1;
  375.       setupterm("dumb", TermOut, NULL);
  376.     }
  377.       else
  378.     {
  379.       if ((TermOut=open("/dev/tty", O_RDWR))<0)
  380.         {
  381.           perror("/dev/tty");
  382.           exit(1);
  383.         }
  384.       setupterm(NULL, TermOut, NULL);
  385.     }
  386.     }
  387.  
  388.   if (TermIn<0)
  389.     TermIn=TermOut;
  390.  
  391.   
  392.   if (BatchMode)
  393.     {
  394.       AddKeyTranslation('\r', "\n",  NULL);
  395.     }
  396.   else
  397.     {
  398.       tcgetattr(TermOut, &OldTerm);
  399.       NewTerm=OldTerm;
  400.       NewTerm.c_iflag &= ~(PARMRK | ISTRIP | INLCR | IGNCR | 
  401.                ICRNL | IUCLC | IXOFF | IXON);
  402.       NewTerm.c_oflag &= ~OPOST;
  403.       NewTerm.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL | IEXTEN);
  404.       NewTerm.c_cc[VMIN]=1;
  405.       NewTerm.c_cc[VTIME]=0;
  406.       tcsetattr(TermOut, TCSANOW, &NewTerm);
  407.  
  408.       if (init_1string)
  409.     write(TermOut, init_1string, strlen(init_1string));
  410.       if (init_2string)
  411.     write(TermOut, init_2string, strlen(init_2string));
  412.       if (init_3string)
  413.     write(TermOut, init_3string, strlen(init_3string));
  414.       if (enter_ca_mode)
  415.     write(TermOut, enter_ca_mode, strlen(enter_ca_mode));
  416.  
  417.       AddKeyTranslation(0x0b, "\033[A",  NULL);
  418.       AddKeyTranslation(0x0a, "\033[B",  NULL);
  419.       AddKeyTranslation(0x15, "\033[C",  NULL);
  420.       AddKeyTranslation(0x08, "\033[D",  NULL);
  421.  
  422.       AddKeyTranslation(0x0b, "\033[OA",  NULL);
  423.       AddKeyTranslation(0x0a, "\033[OB",  NULL);
  424.       AddKeyTranslation(0x15, "\033[OC",  NULL);
  425.       AddKeyTranslation(0x08, "\033[OD",  NULL);
  426.       
  427.       if (key_up)
  428.     AddKeyTranslation(0x0b, key_up,    NULL);
  429.       if (key_down)
  430.     AddKeyTranslation(0x0a, key_down,  NULL);
  431.       if (key_right)
  432.     AddKeyTranslation(0x15, key_right, NULL);
  433.       if (key_left)
  434.     AddKeyTranslation(0x08, key_left,  NULL);
  435.     }
  436. }
  437.  
  438. void TermClose(void)
  439. {
  440.   if (!BatchMode)
  441.     {
  442.       write(TermOut,"\r\n",2);
  443.       if (exit_ca_mode)
  444.     write(TermOut, exit_ca_mode, strlen(exit_ca_mode));
  445.       if (reset_1string)
  446.     write(TermOut, reset_1string, strlen(reset_1string));
  447.       if (reset_2string)
  448.     write(TermOut, reset_2string, strlen(reset_2string));
  449.       if (reset_3string)
  450.     write(TermOut, reset_3string, strlen(reset_3string));
  451.       tcsetattr(TermOut, TCSANOW, &OldTerm);
  452.     }
  453.   else
  454.     write(TermOut,"\n",1);
  455.   close(TermOut);
  456.   close(TermIn);
  457. }
  458. #else
  459. void TermOpen(int UseXTerm, int BatchFd)
  460. {
  461.   TermIn=0;
  462.   TermOut=1;
  463.   rawcon(1);
  464. }
  465.  
  466. void TermClose(void)
  467. {
  468.   rawcon(0);
  469. }
  470.  
  471. char TermRead(void)
  472. {
  473.   signed char    ch;
  474.  
  475.   read(TermIn, &ch, 1);
  476.   return ch;
  477. }
  478.  
  479. int TermStat(void)
  480. {
  481.   return WaitForChar(Input(),1);
  482. }
  483. #endif
  484.